package gui;

// Imports used for listening to certain user input events
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

// Imports used for creating the onscreen components
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

// The controller, used for reading out sensor values
import mechanics.Controller; // The historymaker, used for reading out values from the database
import mechanics.HistoryMaker;

// Swing specific imports
import org.dyno.visual.swing.layouts.Constraints;
import org.dyno.visual.swing.layouts.GroupLayout;
import org.dyno.visual.swing.layouts.Leading;

/**
 * The Instellingen class creates the tab for Instellingen, which controls the
 * hardware's behavings
 * 
 * @version 31-03-2009
 */
public class Instellingen implements ActionListener, ChangeListener, MouseListener {

	// Holds the controller used for communicating with the hardware
	private Controller controller;

	// Holds the historymaker, used to get data from the database
	private HistoryMaker hm;

	// The main panel, containing all other elements
	private JPanel panel;

	// The label which shows a description of the mode options
	private JLabel label_Mode;

	// The label which shows a description of the light options
	private JLabel label_Light;

	// Shows on which value the light bar is currently at
	private JLabel label_Light_Value;

	// The operation mode option buttons
	private ButtonGroup btns_Mode;
	private JRadioButton btn_Mode_Automatisch;
	private JRadioButton btn_Mode_Handmatig;
	private JRadioButton btn_Mode_Uitgeschakeld;

	// The light slider
	private JSlider slider_Light;

	// Dimmer test button
	private JButton dimmer_test;
	
	// Dimmer test label
	private JLabel dimmer_label;

	/**
	 * Constructor loads the controller and creates the historymaker
	 * 
	 * @param controller
	 */
	public Instellingen(Controller controller) {
		this.controller = controller;
		this.hm = new HistoryMaker();
	}

	/**
	 * Creates the panel of this tab
	 * 
	 * @return The panel of the Instellingen tab
	 */
	public JPanel getPanel() {
		if (panel == null) {
			panel = new JPanel();
			panel.setLayout(new GroupLayout());
			panel.add(getModePanel(), new Constraints(new Leading(6, 12, 12), new Leading(10, 12, 12)));
			panel.add(getParametersPanel(), new Constraints(new Leading(6, 12, 12), new Leading(110, 12, 12)));
		}
		return panel;
	}

	/**
	 * Creates the operation mode options panel
	 * 
	 * @return Operation mode panel
	 */
	private JPanel getModePanel() {
		// Create the panel
		JPanel container = new JPanel();

		// Set the mode label
		if (label_Mode == null) {
			label_Mode = new JLabel();
			label_Mode.setText("Mode");
		}

		// Set the button for mode 'automatisch'
		if (btn_Mode_Automatisch == null) {
			btn_Mode_Automatisch = new JRadioButton("Automatisch");
			btn_Mode_Automatisch.setActionCommand("automatisch");
			if (this.getMode().equals("automatisch")) {
				btn_Mode_Automatisch.setSelected(true);
			}
		}

		// Set the button for mode 'handmatig'
		if (btn_Mode_Handmatig == null) {
			btn_Mode_Handmatig = new JRadioButton("Handmatig");
			btn_Mode_Handmatig.setActionCommand("handmatig");
			if (this.getMode().equals("handmatig")) {
				btn_Mode_Handmatig.setSelected(true);
			}
		}

		// Set the button for mode 'uitgeschakeld'
		if (btn_Mode_Uitgeschakeld == null) {
			btn_Mode_Uitgeschakeld = new JRadioButton("Uitgeschakeld");
			btn_Mode_Uitgeschakeld.setActionCommand("uitgeschakeld");
			if (this.getMode().equals("uitgeschakeld")) {
				btn_Mode_Uitgeschakeld.setSelected(true);
			}
		}

		// Create the button group for the various options
		if (btns_Mode == null) {
			btns_Mode = new ButtonGroup();
			btns_Mode.add(btn_Mode_Automatisch);
			btns_Mode.add(btn_Mode_Handmatig);
			btns_Mode.add(btn_Mode_Uitgeschakeld);
		}

		// Create the action listeners, which listen for user input
		btn_Mode_Automatisch.addActionListener(this);
		btn_Mode_Handmatig.addActionListener(this);
		btn_Mode_Uitgeschakeld.addActionListener(this);

		// Load the buttons on the tab
		container.setLayout(new GroupLayout());
		container.add(label_Mode, new Constraints(new Leading(6, 12, 12), new Leading(10, 12, 12)));
		container.add(btn_Mode_Automatisch, new Constraints(new Leading(6, 12, 12), new Leading(30, 12, 12)));
		container.add(btn_Mode_Handmatig, new Constraints(new Leading(6, 12, 12), new Leading(50, 12, 12)));
		container.add(btn_Mode_Uitgeschakeld, new Constraints(new Leading(6, 12, 12), new Leading(70, 12, 12)));

		return container;
	}

	/**
	 * Creates the panel for the parameters
	 * 
	 * @return The parameter panel
	 */
	private JPanel getParametersPanel() {
		// Create the panel
		JPanel container = new JPanel();

		// Sets the light label
		if (label_Light == null) {
			label_Light = new JLabel();
			label_Light.setText("Gewenst licht percentage");
		}

		// Sets the light value label
		if (label_Light_Value == null) {
			label_Light_Value = new JLabel();
			label_Light_Value.setText(this.getLightValue() + "");
		}

		// Creates the slider
		if (slider_Light == null) {
			slider_Light = new JSlider();
			slider_Light.setMinimum(0);
			slider_Light.setMaximum(100);
			slider_Light.setValue(this.getLightValue());
			slider_Light.addChangeListener(this);
			slider_Light.addMouseListener(this);
		}

		if (dimmer_test == null) {
			dimmer_test = new JButton();
			dimmer_test.setText("Test Dimmer");
			dimmer_test.addActionListener(this);
		}
		
		if(dimmer_label == null) {
			dimmer_label = new JLabel();
			dimmer_label.setText("Status: -");
		}

		// Loads the components on to the panel
		container.setLayout(new GroupLayout());
		container.add(label_Light, new Constraints(new Leading(12, 12, 12), new Leading(10, 12, 12)));
		container.add(label_Light_Value, new Constraints(new Leading(180, 12, 12), new Leading(10, 12, 12)));
		container.add(slider_Light, new Constraints(new Leading(6, 12, 12), new Leading(30, 12, 12)));
		container.add(dimmer_test, new Constraints(new Leading(6, 12, 12), new Leading(50, 12, 12)));
		container.add(dimmer_label, new Constraints(new Leading(6, 12, 12), new Leading(80, 12, 12)));

		return container;
	}

	/**
	 * Listenes for actions from the operation mode buttons
	 */
	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(this.dimmer_test)) {
			this.dimmer_label.setText("Testing dimmer..");
			if(this.testDimmer()) {
				this.dimmer_label.setText("Status: OK");
			} else {
				this.dimmer_label.setText("Status: Error");
			}
		} else {
			// If an action is performed, store it in the database
			this.hm.storeSetting("operation_mode", e.getActionCommand());

			if (e.getActionCommand().equals("automatisch")) {
				// Mode = Automatisch
				this.slider_Light.setValue(this.getLightValue());
				this.slider_Light.setEnabled(true);
			} else if (e.getActionCommand().equals("handmatig")) {
				// Mode = Handmatig
				this.slider_Light.setEnabled(true);
			} else if (e.getActionCommand().equals("uitgeschakeld")) {
				// Mode = Uitgeschakeld
				this.controller.setDimmer(0);
				this.slider_Light.setValue(0);
				this.slider_Light.setEnabled(false);
			}
		}
	}

	/**
	 * Listenes for the slider to change it's state
	 */
	public void stateChanged(ChangeEvent e) {
		int value = slider_Light.getValue();

		this.label_Light_Value.setText("" + value);
	}

	private boolean testDimmer() {
		this.controller.setDimmer(0);

		this.controller.setDimmer(100);

		try {
			Thread.sleep(2000);
		} catch (InterruptedException ie) {}

		int light = this.controller.getLight();
		
		System.out.println("Light: " + light);

		this.controller.setDimmer(0);

		if (light >= 50) {
			return true;
		}

		return false;
	}

	/**
	 * Returns the current operation mode
	 * 
	 * @return The operation mode
	 */
	private String getMode() {
		return this.hm.retrieveSetting("operation_mode");
	}

	/**
	 * Returns the desired light value
	 * 
	 * @return The desired light value
	 */
	private int getLightValue() {
		return Integer.valueOf(this.hm.retrieveSetting("light_value"));
	}

	/**
	 * Actions done when the mouse exited the slider
	 */
	public void mouseExited(MouseEvent e) {

	}

	/**
	 * Actions done when the mouse clicked (Pressed and released) the slider
	 */
	public void mouseClicked(MouseEvent e) {

	}

	/**
	 * Actions done when the mouse entered the slider
	 */
	public void mouseEntered(MouseEvent e) {

	}

	/**
	 * Actions done when the mouse pressed the slider
	 */
	public void mousePressed(MouseEvent e) {

	}

	/**
	 * Actions done when the mouse released the slider
	 * 
	 * Set the new value of the dimmer
	 */
	public void mouseReleased(MouseEvent e) {
		// Get the value of the slider
		int value = slider_Light.getValue();

		if (this.getMode().equals("automatisch")) {
			// If the mode is automatisch, store the desired value in the
			// database
			this.hm.storeSetting("light_value", "" + value);
		} else if (this.getMode().equals("handmatig")) {
			// If the mode is handmatig, set the dimmer to the current value
			this.controller.setDimmer((double) value);
		}
	}
}
